﻿/*
	Copyright (C) 2019 Zongming Liu <1849059316@qq.com>

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at your option) any later version.
	
	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.
	
	You should have received a copy of the GNU General Public License along
	with this program; if not, write to the Free Software Foundation, Inc.,
	51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/


#include "_Render.h"
#include "../utility/utility.h"
#include <cmath>
#include "RenderQueue.h"
#include "RenderCommand.h"
#include "CustomCommand.h"
#include "TextCommand.h"
#include "../base/Debuger.h"
#include "QuadCommand.h"
#include "TrianglesCommand.h"
#include "../utility/StringUtility.h"
#include "GeometryCommand.h"
#include "../utility/FastBuffer.h"

using namespace Microsoft::WRL;

namespace SkyEngine2d
{
	
	class Render::Impl
	{
	public:
		Impl();
		~Impl();
		ID3D11Device* getD3dDevice() { return m_d3dDevice.Get(); }
		ID3D11DeviceContext* getD3dDeviceContext() { return m_d3dDeviceContext.Get(); }
		ID3D11RenderTargetView* getD3dRenderTargetView() { return m_renderTargetView.Get(); }
		IDXGISwapChain1* getD3dSwapChain() { return m_swapChain.Get(); }
		ID3D11DepthStencilView* getD3dDepthStencilView() { return m_depthStencilView.Get(); }
		bool initD3dRender(HWND hwnd, UINT w, UINT h);
		void clear(const FLOAT* color_rgba = DirectX::Colors::Blue);
		void present();
		void onResize(HWND hwnd, UINT w, UINT h);
		float getDpi() { return m_dpi.x / 96; }
		ID2D1RenderTarget* getD2dRenderTarget();
	private:
		//初始化硬件
		bool initDevice();
		//D3d设备可能丢失 
		//处理设备丢失的情况
		bool onDeviceLost(HWND hwnd);
		//初始化资源
		bool initResources(HWND hwnd);
	
	
	private:
		//支持的特性等级
		D3D_FEATURE_LEVEL m_featureLevel;
		//D3d设备
		Microsoft::WRL::ComPtr<ID3D11Device>			m_d3dDevice;
		//D3d上下文
		Microsoft::WRL::ComPtr<ID3D11DeviceContext>		m_d3dDeviceContext;
		//交换链
		Microsoft::WRL::ComPtr<IDXGISwapChain1>			m_swapChain;
		//深度模板缓存
		Microsoft::WRL::ComPtr<ID3D11Texture2D >        m_depthStencilBuff;
		//目标渲染视图
		Microsoft::WRL::ComPtr<ID3D11RenderTargetView>  m_renderTargetView;
		//深度模板缓存视图
		Microsoft::WRL::ComPtr<ID3D11DepthStencilView> m_depthStencilView;
		//视口
		CD3D11_VIEWPORT  m_screenViewport;
		//d2d
		Microsoft::WRL::ComPtr<ID2D1RenderTarget>    m_d2dRenderTarget;
		Microsoft::WRL::ComPtr<ID2D1Factory>		m_d2d1Factory;
		int m_outputWidth;
		int m_outputHeight;
	
		HWND m_hwnd;
	
		Vector2 m_dpi;
	};
	
	Render::Impl::Impl()
		:m_hwnd(0)
		, m_swapChain(0)
		, m_d3dDevice(0)
		, m_d3dDeviceContext(0)
		, m_depthStencilView(nullptr)
		, m_outputHeight(1)
		, m_outputWidth(1)
	{
	
	}
	
	Render::Impl::~Impl()
	{
	
	}
	
	
	bool Render::Impl::initD3dRender(HWND hwnd, UINT w, UINT h)
	{
		m_outputWidth = max(w, 1);
		m_outputHeight = max(h, 1);
		m_hwnd = hwnd;
	
		return  initDevice() && initResources(hwnd);
	}
	
	
	void Render::Impl::present()
	{
		auto hr = m_swapChain->Present(0, 0);
		if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET)
		{
			onDeviceLost(m_hwnd);
		}
		else
		{
			checkFailed(hr);
		}
	}
	
	void Render::Impl::onResize(HWND hwnd, UINT w, UINT h)
	{
		m_outputWidth = max(w, 1);
		m_outputHeight = max(h, 1);
		m_hwnd = hwnd;
		if (m_d3dDevice && m_d3dDeviceContext)
		{
			this->initResources(hwnd);
		}
	}
	
	bool Render::Impl::initDevice()
	{
		UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
	#ifdef _DEBUG
		creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
	#endif
	
		static const D3D_FEATURE_LEVEL featureLevels[] =
		{
			D3D_FEATURE_LEVEL_11_1,
			D3D_FEATURE_LEVEL_11_0,
			D3D_FEATURE_LEVEL_10_1,
			D3D_FEATURE_LEVEL_10_0,
			D3D_FEATURE_LEVEL_9_3,
			D3D_FEATURE_LEVEL_9_2,
			D3D_FEATURE_LEVEL_9_1,
		};
		try
		{
			ComPtr<ID3D11Device> device;
			ComPtr<ID3D11DeviceContext> context;
			checkFailed(D3D11CreateDevice(
				nullptr,
				D3D_DRIVER_TYPE_HARDWARE,
				nullptr,
				creationFlags,
				featureLevels,
				_countof(featureLevels),
				D3D11_SDK_VERSION,
				device.ReleaseAndGetAddressOf(),
				&m_featureLevel,
				context.ReleaseAndGetAddressOf()
			), "创建D3d11设备失败");
			checkFailed(device.As(&m_d3dDevice));
			checkFailed(context.As(&m_d3dDeviceContext));
	
			if (m_featureLevel < D3D_FEATURE_LEVEL_11_0)
			{
				throw std::exception("你的机器貌似不支持DX11");
			}
	
			//2D 工厂
			D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, m_d2d1Factory.ReleaseAndGetAddressOf());
		}
		catch (const std::exception & e)
		{
			MessageBox(0, StringUtility::charToWchar(e.what()).c_str(), 0, 0);
			return false;
		}
		return true;
	}
	
	bool Render::Impl::onDeviceLost(HWND hwnd)
	{
		m_depthStencilView.Reset();
		m_renderTargetView.Reset();
		m_swapChain.Reset();
		m_d3dDeviceContext.Reset();
		m_d3dDevice.Reset();
		m_d2dRenderTarget.Reset();
	
		return initDevice() && initResources(hwnd);
	}
	
	bool Render::Impl::initResources(HWND hwnd)
	{
		try
		{
			// 清空之前的上下文
			ID3D11RenderTargetView* nullViews[] = { nullptr };
			m_d3dDeviceContext->OMSetRenderTargets(_countof(nullViews), nullViews, nullptr);
			m_renderTargetView.Reset();
			m_depthStencilView.Reset();
			m_d3dDeviceContext->Flush();
			m_depthStencilBuff.Reset();
			m_d2dRenderTarget.Reset();
	
			//创建交换链
			UINT backBufferWidth = static_cast<UINT>(m_outputWidth);
			UINT backBufferHeight = static_cast<UINT>(m_outputHeight);
			DXGI_FORMAT backBufferFormat = DXGI_FORMAT_B8G8R8A8_UNORM;
			DXGI_FORMAT depthBufferFormat = DXGI_FORMAT_D24_UNORM_S8_UINT;
			UINT backBufferCount = 2;
	
			if (m_swapChain)//如果已经存在
			{
				HRESULT hr = m_swapChain->ResizeBuffers(backBufferCount, backBufferWidth, backBufferHeight, backBufferFormat, 0);
				//如果设备丢失
				if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET)
				{
					return onDeviceLost(hwnd);
				}
				else
				{
					checkFailed(hr);
				}
			}
			else
			{
				//重新创建交换链
				//1.获取 IDXGIFactory2 对象
				//2.使用 IDXGIFactory2 对象 创建交换链
				ComPtr<IDXGIDevice1> dxgiDevice;
				checkFailed(m_d3dDevice.As(&dxgiDevice));
				ComPtr<IDXGIAdapter> dxgiAdapter;
				checkFailed(dxgiDevice->GetAdapter(dxgiAdapter.GetAddressOf()));
				ComPtr<IDXGIFactory2> dxgiFactory;
				checkFailed(dxgiAdapter->GetParent(IID_PPV_ARGS(dxgiFactory.GetAddressOf())));
	
				DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {};
				swapChainDesc.Width = backBufferWidth;
				swapChainDesc.Height = backBufferHeight;
				swapChainDesc.Format = backBufferFormat;
				swapChainDesc.SampleDesc.Count = 1;
				swapChainDesc.SampleDesc.Quality = 0;
				swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
				swapChainDesc.BufferCount = backBufferCount;
	
	
				DXGI_SWAP_CHAIN_FULLSCREEN_DESC fsSwapChainDesc = {};
				fsSwapChainDesc.Windowed = TRUE;
	
				checkFailed(dxgiFactory->CreateSwapChainForHwnd(
					m_d3dDevice.Get(),
					hwnd,
					&swapChainDesc,
					&fsSwapChainDesc,
					nullptr,
					m_swapChain.ReleaseAndGetAddressOf()
				));
	
	
			}
	
			//创建D2d渲染目标
			ComPtr<IDXGISurface> buffer;
			m_swapChain->GetBuffer(0, IID_PPV_ARGS(buffer.ReleaseAndGetAddressOf()));
	
			FLOAT dpiX;
			FLOAT dpiY;
	
			m_d2d1Factory->GetDesktopDpi(&dpiX, &dpiY);
	
			D2D1_RENDER_TARGET_PROPERTIES props =
				D2D1::RenderTargetProperties(
					D2D1_RENDER_TARGET_TYPE_DEFAULT,
					D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED),
					dpiX,
					dpiY
				);
			checkFailed(m_d2d1Factory->CreateDxgiSurfaceRenderTarget(
				buffer.Get(),
				&props,
				m_d2dRenderTarget.ReleaseAndGetAddressOf()
			));
	
			m_d2dRenderTarget->GetDpi(&m_dpi.x, &m_dpi.y);
	
			//创建渲染目标视图
			ComPtr<ID3D11Texture2D> backBuffer;
			checkFailed(m_swapChain->GetBuffer(0, IID_PPV_ARGS(backBuffer.GetAddressOf())));
			checkFailed(m_d3dDevice->CreateRenderTargetView(backBuffer.Get(), nullptr, m_renderTargetView.ReleaseAndGetAddressOf()));
	
			//创建 模板/深度缓存视图
			CD3D11_TEXTURE2D_DESC depthStencilDesc(depthBufferFormat, backBufferWidth, backBufferHeight, 1, 1, D3D11_BIND_DEPTH_STENCIL);
			checkFailed(m_d3dDevice->CreateTexture2D(&depthStencilDesc, nullptr, m_depthStencilBuff.ReleaseAndGetAddressOf()));
			CD3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc(D3D11_DSV_DIMENSION_TEXTURE2D);
			checkFailed(m_d3dDevice->CreateDepthStencilView(m_depthStencilBuff.Get(), &depthStencilViewDesc, m_depthStencilView.ReleaseAndGetAddressOf()));
	
			//设置渲染目标
			m_d3dDeviceContext->OMSetRenderTargets(1, m_renderTargetView.GetAddressOf(), m_depthStencilView.Get());
	
			//视口
			m_screenViewport.TopLeftX = 0;
			m_screenViewport.TopLeftY = 0;
			m_screenViewport.Width = static_cast<float>(m_outputWidth);
			m_screenViewport.Height = static_cast<float>(m_outputHeight);
			m_screenViewport.MinDepth = 0.0f;
			m_screenViewport.MaxDepth = 1.0f;
	
			m_d3dDeviceContext->RSSetViewports(1, &m_screenViewport);
	
		}
		catch (const std::exception & e)
		{
			MessageBoxA(0, e.what(), 0, 0);
			return false;
		}
		return true;
	}
	
	void Render::Impl::clear(const FLOAT* color_rgba /*=DirectX::Colors::Blue*/)
	{
		m_d3dDeviceContext->ClearRenderTargetView(m_renderTargetView.Get(), color_rgba);
		m_d3dDeviceContext->ClearDepthStencilView(m_depthStencilView.Get(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
	}
	
	ID2D1RenderTarget* Render::Impl::getD2dRenderTarget()
	{
		return  m_d2dRenderTarget.Get();
	}
	
	
	ID2D1RenderTarget* Render::getD2dRenderTarget()
	{
		return m_d3dData->getD2dRenderTarget();
	}
	
	float Render::getDpi()
	{
		return m_d3dData->getDpi();
	}
	
	bool Render::init(HWND hwnd, UINT w, UINT h)
	{
		return m_isInit = m_d3dData->initD3dRender(hwnd, w, h);
	}

	///////////////VIBuffer////////////////////////////////////////
	
	struct Render::VIBuffer
	{
		//顶点缓存区
		FastBuffer<VertexPositionTexture> m_vertexBuffer;
		//索引缓存区
		FastBuffer<UINT> m_indexBuffer;
	};
	
	
	///////////////////////////// Class Render /////////////////////////////////////
	
	
	inline ID3D11Device* Render::getD3dDevice()
	{
		return m_d3dData->getD3dDevice();
	}
	
	inline ID3D11DeviceContext* Render::getD3dDeviceContext()
	{
		return m_d3dData->getD3dDeviceContext();
	}
	
	inline ID3D11RenderTargetView* Render::getD3dRenderTargetView()
	{
		return m_d3dData->getD3dRenderTargetView();
	}
	
	inline IDXGISwapChain1* Render::getD3dSwapChain()
	{
		return m_d3dData->getD3dSwapChain();
	}
	
	inline ID3D11DepthStencilView* Render::getD3dDepthStencilView()
	{
		return m_d3dData->getD3dDepthStencilView();
	}
	
	void Render::ClearDirect3D()
	{
	
	}
	
	void Render::onResize(HWND hwnd, UINT w, UINT h)
	{
		return m_d3dData->onResize(hwnd, w, h);
	}
	
	Render::Render()
		:m_d3dData(std::make_unique<Render::Impl>())
		, m_renderQueue(std::make_unique<RenderQueue>())
		, m_isInit(false)
		, m_currentBatVertexCount(0)
		, m_lastCmdtype(RenderCommand::Type::NoneCommand)
		, m_currentBatAllIndexCount(0)
		, m_currentBatAllVertexCount(0)
		, m_vertexIndexBuffer(nullptr)
	{
		m_clearColor[0] = Color::Green.x;
		m_clearColor[1] = Color::Green.y;
		m_clearColor[2] = Color::Green.z;
		m_clearColor[3] = Color::Green.w;
	
		m_vertexIndexBuffer = new VIBuffer;
	
		//渲染命令 预分配1000
		m_randerTrianglesQueue.reserve(1000);
	
		this->clearBathDrawTriangles();
	}

	Render::~Render()
	{
		delete m_vertexIndexBuffer;
	}
	
	
	void Render::processRenderCmd(RenderCommand* cmd)
	{
		//绘制命令数统计
		m_drawCmdCount++;
	
		auto type = cmd->getType();
		//处理三角形渲染命令
		if (type == RenderCommand::Type::TrianglesCommand || type == RenderCommand::Type::Scale9ImageCommand)
		{
			IBatDrawCommand* c = dynamic_cast<IBatDrawCommand*>(cmd);
			DebugerAssert(c, "命令指针转换失败");
			if (c)
			{
				m_currentBatAllIndexCount += c->getIndexCount();
				m_currentBatAllVertexCount += c->getVertexCount();
	
				m_randerTrianglesQueue.push_back(c);
			}
		}
		//处理自由命令
		else if (type == RenderCommand::Type::CustomCommand)
		{
			((CustomCommand*)cmd)->drawFunc();
		}
		//处理文本绘制
		else if (type == RenderCommand::Type::TextCommand)
		{
			auto c = dynamic_cast<TextCommand*>(cmd);
			if (c)
			{
				c->execute(this);
			}
			else
			{
				DebugWarning("渲染命令转化失败 TextCommand");
			}
		}
		else if (type == RenderCommand::Type::GeometryCommand)
		{
			auto c = dynamic_cast<GeometryCommand*>(cmd);
			if (c)
			{
				c->draw(this);
				delete c;
			}
		}
	
		if ((m_lastCmdtype == RenderCommand::Type::TrianglesCommand || m_lastCmdtype == RenderCommand::Type::Scale9ImageCommand)
			&& (type != RenderCommand::Type::TrianglesCommand && type != RenderCommand::Type::Scale9ImageCommand))
		{
			this->batchDrawTriangles();
		}
	
		m_lastCmdtype = type;
	}
	
	
	
	void Render::batchDrawTriangles()
	{
		if (m_randerTrianglesQueue.size() <= 0)
		{
			return;
		}
	
		//预先分配 缓存
		//m_indexBuffer.resize(m_currentBatAllIndexCount);
		//m_vertexBuffer.reserve(m_currentBatAllVertexCount);
		m_vertexIndexBuffer->m_indexBuffer.reserve(m_currentBatAllIndexCount);
		m_vertexIndexBuffer->m_vertexBuffer.reserve(m_currentBatAllVertexCount);
	
		//
		bool isFirst = true;
		TrianglesBat bat{ nullptr,0,0,0 };
		int i = -1;
		//合并顶点、索引缓存
		for (auto cmd : m_randerTrianglesQueue)
		{
			if (m_lastCmdMatrix != nullptr && cmd->getMaterial() == *m_lastCmdMatrix)
			{
				m_batDrawVector[i].indexCount += cmd->getIndexCount();
			}
			else
			{
				bat.cmd = cmd;
				bat.indexCount = cmd->getIndexCount();
				bat.startIndexPos = m_fillIndexCount;
				bat.startVertexPos = m_fillVertexCount;
				i++;
				m_batDrawVector.push_back(bat);
				m_lastCmdMatrix = &cmd->getMaterial();
				m_currentBatVertexCount = 0;
			}
			this->fillVerticesAndIndex(cmd);
	
		}
	
		//d3d 上下文设备
		auto d3dContext_ = this->getD3dDeviceContext();
		auto d3dDevice_ = this->getD3dDevice();
	
		//设置顶点索引缓存
	
		D3D11_BUFFER_DESC vertexDesc;
		ZeroMemory(&vertexDesc, sizeof(vertexDesc));
		vertexDesc.Usage = D3D11_USAGE_DEFAULT;
		vertexDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
		vertexDesc.ByteWidth = sizeof(VertexPositionTexture) * m_vertexIndexBuffer->m_vertexBuffer.getSize();
	
		D3D11_SUBRESOURCE_DATA resourceData;
		ZeroMemory(&resourceData, sizeof(resourceData));
		resourceData.pSysMem = m_vertexIndexBuffer->m_vertexBuffer.getData();
	
		//初始化顶点缓存  
		Microsoft::WRL::ComPtr<ID3D11Buffer> vertexBuffer;
		Microsoft::WRL::ComPtr<ID3D11Buffer> IndexBuffer;
		checkFailed(d3dDevice_->CreateBuffer(&vertexDesc, &resourceData, vertexBuffer.ReleaseAndGetAddressOf()));
	
		D3D11_BUFFER_DESC ibd;
		ZeroMemory(&ibd, sizeof(ibd));
		ibd.Usage = D3D11_USAGE_IMMUTABLE;
		ibd.ByteWidth = sizeof(UINT) * m_vertexIndexBuffer->m_indexBuffer.getSize();
		ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;
	
		D3D11_SUBRESOURCE_DATA iinitData;
		ZeroMemory(&iinitData, sizeof(iinitData));
		iinitData.pSysMem = m_vertexIndexBuffer->m_indexBuffer.getData();
	
		checkFailed(d3dDevice_->CreateBuffer(&ibd, &iinitData, IndexBuffer.ReleaseAndGetAddressOf()));
	
		//绑定缓存
		unsigned int stride = sizeof(VertexPositionTexture);
		unsigned int offse = 0;
		d3dContext_->IASetVertexBuffers(0, 1, vertexBuffer.GetAddressOf(), &stride, &offse);
		d3dContext_->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
		d3dContext_->IASetIndexBuffer(IndexBuffer.Get(), DXGI_FORMAT_R32_UINT, 0);
	
		for (auto b : m_batDrawVector)
		{
			b.cmd->use(this);
			d3dContext_->DrawIndexed(b.indexCount, b.startIndexPos, b.startVertexPos);
			m_drawCall++;
		}
	
		this->clearBathDrawTriangles();
	}
	
	
	void Render::clearBathDrawTriangles()
	{
		m_randerTrianglesQueue.clear();
		m_vertexIndexBuffer->m_vertexBuffer.clear();
		m_vertexIndexBuffer->m_indexBuffer.clear();
		m_batDrawVector.clear();
		m_fillVertexCount = 0;
		m_fillIndexCount = 0;
		m_currentBatAllVertexCount = 0;
		m_currentBatAllIndexCount = 0;
		m_lastCmdMatrix = nullptr;
	}
	
	void Render::fillVerticesAndIndex(IBatDrawCommand* cmd)
	{
		const auto& vertex = cmd->getVertexBuffer();
		int vcount = vertex.size();
	
		m_vertexIndexBuffer->m_vertexBuffer.append(vertex.data(), vcount);
	
		const auto& index = cmd->getIndexBuffer();
		int icount = index.size();
		auto& indexBuffer = m_vertexIndexBuffer->m_indexBuffer;
		indexBuffer.append(index.data(), icount);
		for (int j = m_fillIndexCount; j < icount + m_fillIndexCount; j++)
		{
			indexBuffer[j] += m_currentBatVertexCount;
		}
	
		m_fillVertexCount += vcount;
		m_fillIndexCount += icount;
		m_currentBatVertexCount += vcount;
	
		//统计每帧绘制的顶点数
		m_vertexCount += vcount;
	}
	
	
	void Render::setClearColor(const Color& clear_color)
	{
		m_clearColor[0] = clear_color.x;
		m_clearColor[1] = clear_color.y;
		m_clearColor[2] = clear_color.z;
		m_clearColor[3] = clear_color.w;
	}
	
	bool Render::isInit() const
	{
		return m_isInit;
	}
	
	int Render::getDrawCallCount()
	{
		return m_drawCall;
	}
	
	int Render::getDrawCmdCount()
	{
		return m_drawCmdCount;
	}
	
	int Render::getVertexCount()
	{
		return m_vertexCount;
	}
	
	void Render::renderBegin()
	{
		m_d3dData->clear(m_clearColor);
		m_drawCall = 0;
		m_drawCmdCount = 0;
		m_vertexCount = 0;
	
		this->getD2dRenderTarget()->BeginDraw();
	}
	
	HRESULT Render::renderEnd()
	{
		HRESULT hr = this->getD2dRenderTarget()->EndDraw();
		m_d3dData->present();
		return hr;
	}
	
	void Render::addRenderCommand(RenderCommand* cmd)
	{
		m_renderQueue->pushRenderCommand(cmd);
	}
	
	void Render::render()
	{
		//1.排序
		m_renderQueue->sort();
	
		//2.处理各个渲染队列
	
		// z<0
		auto& queue_low = m_renderQueue->getRenderQueue(RenderQueue::GLOABL_ZORDER_LOW);
		if (queue_low.size() > 0)
		{
			for (const auto& cmd : queue_low)
			{
				processRenderCmd(cmd);
			}
			batchDrawTriangles();
		}
		//z==0
		auto& queue_zero = m_renderQueue->getRenderQueue(RenderQueue::GLOABL_ZORDER_ZERO);
		if (queue_zero.size() > 0)
		{
			for (const auto& cmd : queue_zero)
			{
				processRenderCmd(cmd);
			}
			batchDrawTriangles();
		}
		//z>0
		auto& queue_pre = m_renderQueue->getRenderQueue(RenderQueue::GLOABL_ZORDER_PRECEDENCE);
		if (queue_pre.size() > 0)
		{
			for (const auto& cmd : queue_pre)
			{
				processRenderCmd(cmd);
			}
			batchDrawTriangles();
		}
	
		//3.清理队列
		m_renderQueue->clear();
	}
	
	
	SkyEngine2d::IDirectRender* Render::getDirectRender()
	{
		assert(this->isInit());
		return this;
	}

}
